#pragma once

#include "znx_defs.h"
#include "znx_atomic.h"


typedef znx_atomic_int64_t          znx_spinlock_t;

#define ZNX_SPINLOCK_INITLIZER      0

#define ZNX_LOCK_SPIN               5

static inline void
znx_spinlock_init(znx_spinlock_t *lock)
{
    znx_atomic_int64_reset(lock);
}

void znx_spinlock_lock(znx_spinlock_t *lock);
znx_bool_t znx_spinlock_trylock(znx_spinlock_t *lock);

static inline void
znx_spinlock_unlock(znx_spinlock_t *lock) {
    if (!znx_atomic_int64_cas(lock, 1, 0)) {
        ZNX_ASSERT_FATAL("unexcept state");
    }
}


typedef znx_atomic_int64_t                      znx_spin_wait_group_t;

#define ZNX_SPIN_WAIT_GROUP_INITLIZER           0

static inline void
znx_spin_wait_group_init(znx_spin_wait_group_t *wait_group)
{
    znx_atomic_int64_reset(wait_group);
}

static inline void
znx_spin_wait_group_add(znx_spin_wait_group_t *wait_group, int64_t incr)
{
    znx_atomic_int64_fetch_add(wait_group, incr);
}

static inline void
znx_spin_wait_group_done(znx_spin_wait_group_t *wait_group)
{
    znx_atomic_int64_fetch_add(wait_group, -1);
}

void znx_spin_wait_group_wait(znx_spin_wait_group_t *wait_group);
